package cn.green.core.adapt.models.field;

import cn.green.core.adapt.models.field.abs.AbsOrmField;
import cn.green.core.adapt.models.table.OrmTable;
import cn.green.core.annos.column.QColumn;
import cn.green.core.annos.reles.OneToOne;
import cn.green.core.annos.table.QTable;
import cn.green.core.model.QFieldModel;
import cn.green.core.model.QTableModel;
import cn.green.core.scanner.store.OrmTableStore;
import cn.green.utils.ColumnUtils;
import com.alibaba.fastjson.JSONObject;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * @author wang.yishu
 * @version 1.0
 * @className OrmOneToOne
 * @description 一对一关系
 * @date 2025/5/14 09:47
 */
@EqualsAndHashCode(callSuper = true)
@Data
public class OrmOneToOne extends AbsOrmField {
    private Class<?> targetClazz;

    private Map<String, String> columnMap;

    public OrmOneToOne(Class<?> clazz, QTableModel table, Field field) {
        super(clazz, table, field);
        if (field == null) {
            throw new NullPointerException("field is null");
        }
        if (table == null) {
            throw new NullPointerException("table is null");
        }
        OneToOne annotation = field.getAnnotation(OneToOne.class);
        if (annotation == null) {
            return;
        }
        this.table = table;
        this.field = field;
        this.sourceName = this.table.getSourceName();
        this.schemeName = this.table.getSchemeName();
        this.tableName = this.table.getTableName();
        this.fieldName = field.getName();
        this.aliasName = annotation.alias();
        this.uniqueCode = this.fieldName;
        this.fieldType = "ORM_ONE_TO_ONE";
        String targetSource = "";
        String targetSchema = "";
        String targetTable = "";
        //目标表类型
        Class<?> target = annotation.target();
        if (target == JSONObject.class) {
            targetSource = annotation.source();
            targetSchema = annotation.scheme();
            targetTable = annotation.table();
            this.targetClazz = JSONObject.class;
        } else {
            QTable targetQTable = target.getDeclaredAnnotation(QTable.class);
            if (targetQTable == null) {
                throw new NullPointerException("targetTable is null");
            }
            targetSource = targetQTable.source();
            targetSchema = targetQTable.scheme();
            targetTable = targetQTable.name();
            this.targetClazz = target;
        }
        //开始执行
        String[] mapping = annotation.mapping();
        if (mapping == null || mapping.length == 0) {
            throw new NullPointerException("mapping is null");
        }
        this.columnMap = new HashMap<>();
        for (String map : mapping) {
            String trim = map.trim();
            if (trim.isEmpty()) {
                throw new NullPointerException("map is empty");
            }
            String[] split = trim.split("=");
            if (split.length != 2) {
                throw new NullPointerException("map string is wrong");
            }
            String currentColumn = "";
            String targetColumn = "";
            Field curField = null;
            Field tarField = null;
            //本表
            String cur = split[0];
            //目标
            String tar = split[1];
            try {
                curField = this.clazz.getDeclaredField(cur);
            } catch (NoSuchFieldException ignore) {
            }
            try {
                tarField = this.targetClazz.getDeclaredField(tar);
            } catch (NoSuchFieldException ignore) {
            }
            //todo 这里需要修改
            QFieldModel curColumn = null;
            QFieldModel tarColumn = null;
            if (curField != null) {
                //如果有对应的属性，则说明是根据属性名称来的
                curColumn = ColumnUtils.getField(this.clazz, curField);
            } else {
                //如果有没有对应的属性，则说明是根据字段名称来的
                curColumn = ColumnUtils.getField(this.sourceName, this.schemeName, this.tableName, cur);
            }
            if (tarField != null) {
                //如果有对应的属性，则说明是根据属性名称来的
                tarColumn = ColumnUtils.getField(this.targetClazz, tarField);
            } else {
                //如果有没有对应的属性，则说明是根据字段名称来的
                tarColumn =ColumnUtils.getField(targetSource, targetSchema, targetTable, tar);
            }
            if (curColumn == null || tarColumn == null) {
                throw new NullPointerException("OneToOne config: mapping set wrong! ");
            }
            currentColumn = curColumn.getFieldName();
            targetColumn = tarColumn.getFieldName();
            this.columnMap.put(currentColumn, targetColumn);
        }
        this.status = "1";
        JSONObject config = new JSONObject();
        config.put("fieldName", field.getName());
        config.put("targetClazz", this.targetClazz.getName());
        config.put("targetSource", targetSource);
        config.put("targetScheme", targetSchema);
        config.put("targetTableName", targetTable);
        config.put("columnMap", this.columnMap);
        this.setConfigObj(config);
    }

    @Override
    public boolean canBeInTable() {
        return false;
    }
}
